package com.tdcy.framework.dao.orm;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.RowMapper;

import com.tdcy.framework.annotation.Column;
import com.tdcy.framework.exception.BaseException;
import com.tdcy.framework.util.DateUtils;
import com.tdcy.framework.util.ReflectUtils;

@SuppressWarnings("rawtypes")
public class CommonRowMapper implements RowMapper {

	private static final Logger logger = LoggerFactory.getLogger(CommonRowMapper.class);

	private Class clz;
	private Map<String, String> fieldNames = new HashMap<String, String>();

	public CommonRowMapper(Class clz) {
		this.clz = clz;
		List<Field> fields = ReflectUtils.getClassFields(clz, true);
		for (int i = 0; i < fields.size(); i++) {
			Field field = fields.get(i);
			boolean hasAnnotation = field.isAnnotationPresent(Column.class);
			if (hasAnnotation) {
				Column annotation = (Column) field.getAnnotation(Column.class);
				fieldNames.put(annotation.name().toLowerCase(), field.getName());
			}
		}
	}

	public Object mapRow(ResultSet arg0, int arg1) throws SQLException {
		try {
			Object obj = clz.newInstance();
			ResultSetMetaData meta = arg0.getMetaData();
			int iCount = meta.getColumnCount();
			for (int i = 1; i <= iCount; i++) {
				String colName = meta.getColumnName(i).toLowerCase();
				String labelName = meta.getColumnLabel(i).toLowerCase();
				String colType = meta.getColumnTypeName(i);
				Object value = arg0.getObject(i);

				// System.out.println(meta.getColumnLabel(i)+","+colName+","+colType+","+value.getClass()+","+value);
				if (value instanceof Date) {
					// value = arg0.getTimestamp(i);// new
					// Timestamp(((Date)value).getTime());
					// DateUtils.toDate(date)
					value = DateUtils.toDate(arg0.getTimestamp(i));
				} else if (colType.equals("LONGBLOB") || colType.equals("MEDIUMBLOB") || colType.equals("BLOB") || colType.equals("VARBINARY")) {
					byte[] bs = (byte[]) value;
					value = bs;
				}
				if (fieldNames.get(labelName) != null && value != null) {
					BeanUtils.setProperty(obj, fieldNames.get(labelName), value);
				}
			}
			return obj;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new BaseException(e.getMessage(), e);
		}
	}

}
